import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:my_app/navigation.dart';
import 'package:my_app/pages/api_demo.dart';
import 'package:my_app/pages/generic_error_screen.dart';
import 'package:my_app/pages/not_found.dart';
import 'package:my_app/pages/page_not_found_screen.dart';
import 'package:my_app/pages/plugin_demo.dart';
import 'package:my_app/pages/unauthorized_screen.dart';
import 'package:my_app/pages/widget_demo.dart';

import 'api_router.dart';
import 'plugin_router.dart';
import 'widget_router.dart';

final _rootKey = GlobalKey<NavigatorState>(debugLabel: "root");
final _rootRouteKey = GlobalKey<NavigatorState>(debugLabel: "rootShellRoute");

/// 使用dart3.x的增强枚举来集中管理路由地址与页面
/// 
/// 便于使用Ctrl+鼠标左键查看对应页面
/// 
/// 如果有需要，也可增加name选项
void test() {}

enum NavigationRouters {
  // demo('/demo'),
  widgetDemo('/widget-demo', WidgetDemoPage()),
  pluginDemo('/plugin-demo', PluginDemoPage()),
  apiDemo('/api-demo', ApiDemoPage()),
  ;

  const NavigationRouters(this.path, this.page);

  final String path;
  final Widget page;
}

final _navigatorRoute = [
  ShellRoute(
    navigatorKey: _rootRouteKey,
    builder: (context, state, child) => NavigationPage(child: child),
    routes: <RouteBase>[
      GoRoute(
        path: NavigationRouters.widgetDemo.path,
        pageBuilder: (context, state) {
          return CustomTransitionPage(
            key: state.pageKey,
            child: NavigationRouters.widgetDemo.page,
            transitionsBuilder: (context, animation, secondaryAnimation, child) {
              return child;
            }
          );
        }
      ),
      GoRoute(
        path: NavigationRouters.pluginDemo.path,
        pageBuilder: (context, state) {
          return CustomTransitionPage(
            key: state.pageKey,
            child: NavigationRouters.pluginDemo.page,
            transitionsBuilder: (context, animation, secondaryAnimation, child) {
              return child;
            }
          );
        }
      ),
      // 如果要给路由切换增加自定义动画，需使用pageBuilder
      GoRoute(
        path: NavigationRouters.apiDemo.path,
        pageBuilder: (context, state) {
          return CustomTransitionPage(
            key: state.pageKey,
            child: NavigationRouters.apiDemo.page,
            transitionsBuilder: (context, animation, secondaryAnimation, child) {
              return child;
            }
          );
        }
      )
    ],
  ),
  GoRoute(
    parentNavigatorKey: _rootKey,
    path: '/page-not-found',
    builder: (context, state) {
      return NotFoundPage(uri: state.extra as String? ?? "");
    }
  ),
  GoRoute(
    parentNavigatorKey: _rootKey,
    path: '/a',
    builder: (context, state) {
      return const PageNotFoundScreen();
    }
  ),
  GoRoute(
    parentNavigatorKey: _rootKey,
    path: '/b',
    builder: (context, state) {
      return const UnauthorizedScreen();
    }
  ),
  GoRoute(
    parentNavigatorKey: _rootKey,
    path: '/c',
    builder: (context, state) {
      return const GenericErrorScreen();
    }
  )
];

final GoRouter router = GoRouter(
  debugLogDiagnostics: true, // 打印跳转日志
  initialLocation: "/widget-demo",
  navigatorKey: _rootKey,
  routes: [
      _navigatorRoute,
      generateWidgetRoutes(_rootKey),
      generatePluginRoutes(_rootKey),
      generateApiRoutes(_rootKey)
    ].expand((element) => element).toList(),
  
  // 连error/exception信息都没有
  onException: (_, GoRouterState state, GoRouter router) {
    // 使用push才能回到原来跳转的页面
    router.push('/page-not-found', extra: state.location.toString());
  },
  // errorBuilder: (context, state) {
  //   WidgetsBinding.instance.addPostFrameCallback((_) {
  //     // 经过观察，目前应该是不支持具体的Exception类型
  //     // https://github.com/flutter/flutter/issues/99109
  //     if (state.error is PageNotFoundException) {
  //       // 跳转到页面未找到的错误页面
  //       context.replace('/a');
  //     } else if (state.error is UnauthorizedException) {
  //       // 跳转到未授权的错误页面
  //       context.replace('/b');
  //     } else {
  //       // 跳转到其他错误页面
  //       context.replace('/c');
  //     }
  //   });
  //   return Container();
  // },
);

class PageNotFoundException implements Exception {}

class UnauthorizedException implements Exception {}

